<template>
  <div
    v-show="otherData.bzdw && visible"
    :style="{fontSize: sizeMap[otherData.bzFontSize] + 'px', color: otherData.bzColor,left: left + 'px', top: top + 'px'}"
    @mousedown="handleMouseDown"
    ref="self"
    class="bzdw-container"
  >
    {{ text }}
  </div>
</template>

<script>
import { sizesList, sizeMap } from '../utils'
import { mapState } from 'vuex'
import { debounce } from 'throttle-debounce'
export default {
  name: 'BzdwContainer',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    containerWidth: {
      type: Number,
      default: 0
    },
    containerHeight: {
      type: Number,
      default: 0
    }
  },
  data () {
    return {
      visible: this.value,
      left: 0,
      top: 200,
      sizeList: sizesList,
      sizeMap: sizeMap,
      loaded: false
    }
  },
  created () {
    this.debounceCommit = debounce(800, this.updateFontPosition)
    this.$root.$on('updateMapMaking', this.updateMapMaking)
  },
  beforeDestroy () {
    this.$root.$off('updateMapMaking', this.updateMapMaking)
  },
  computed: {
    ...mapState('map-making', ['otherData']),
    text () {
      return this.otherData.bzdw + '制'
    }
  },
  watch: {
    value (v) {
      this.visible = v
    },
    visible (v) {
      this.$emit('input', v)
      if (this.visible && this.otherData.bzdw && !this.loaded) {
        this.$nextTick(() => {
          this.left = Math.floor(this.containerWidth / 2) - (this.$refs.self.offsetWidth / 2)
          this.top = 200
          this.loaded = true
          this.updateFontPosition()
        })
      }
    },
    containerWidth (v, old) {
      this.oldWidth = old
      this.updatePosition()
    },
    containerHeight (v, old) {
      this.oldHeight = old
      this.updatePosition()
    }
  },
  methods: {
    updateMapMaking () {
      if (!isNaN(Number(this.otherData.bzLeft)) && !isNaN(Number(this.otherData.bzTop))) {
        this.left = Number(this.otherData.bzLeft) * this.containerWidth
        this.top = Number(this.otherData.bzTop) * this.containerHeight
        this.loaded = true
      }
    },
    handleMouseDown (e) {
      this.mouseX = e.x
      this.mouseY = e.y
      this.currentLeft = this.left
      this.currentTop = this.top
      this.dragging = true
      document.body.addEventListener('mousemove', this.handleMouseMove)
      document.body.addEventListener('mouseup', this.handleMouseUp)
    },
    handleMouseMove (e) {
      if (!this.dragging) return
      this.$refs.self.style.cursor = 'move'
      const left = this.currentLeft + (e.x - this.mouseX)
      const top = this.currentTop + (e.y - this.mouseY)
      this.left = Math.min(Math.max(0, left), this.containerWidth - this.$refs.self.offsetWidth)
      this.top = Math.min(Math.max(0, top), this.containerHeight - this.$refs.self.offsetHeight)
      this.debounceCommit()
    },
    handleMouseUp () {
      this.dragging = false
      document.body.removeEventListener('mousemove', this.handleMouseMove)
      document.body.removeEventListener('mouseup', this.handleMouseUp)
    },
    updateFontPosition () {
      this.$store.commit('map-making/setOtherData', Object.assign(this.otherData, { bzLeft: this.left / this.containerWidth, bzTop: this.top / this.containerHeight }))
    },
    formatterDate (date) {
      return this.$utils.createDate(date).format('YYYY年MM月DD日')
    },
    updatePosition () {
      if (this.oldWidth && this.oldHeight) {
        const leftRatio = this.left / this.oldWidth
        const topRatio = this.top / this.oldHeight
        this.left = Math.min(Math.max(0, leftRatio * this.containerWidth), this.containerWidth - this.$refs.self.offsetWidth)
        this.top = Math.min(Math.max(0, topRatio * this.containerHeight), this.containerHeight - this.$refs.self.offsetHeight)
        this.oldWidth = null
        this.oldHeight = null
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.bzdw-container {
  position: absolute;
  cursor: move;
  user-select: none;
  z-index: 5;
  white-space: nowrap;
  padding: 5px 10px;
  background: transparent;
}
</style>
